package com.lzw.service.impl;

import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsRequest;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsResponse;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse;
import com.aliyuncs.exceptions.ClientException;
import com.lzw.dto.GetHostIpResponseVo;
import com.lzw.http.IGetHostIp;
import com.lzw.service.IDNSService;
import com.lzw.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author liuzw
 * @date 2021/10/29
 */
@Slf4j
@Service
@RestController
public class DNSServiceImpl implements IDNSService {

    private final IGetHostIp hostIp;
    @Value("${domain.name}")
    private String domainName;
    @Value("${rr.key.word:www}")
    private String rRKeyWord;
    @Autowired
    private IAcsClient client;

    public DNSServiceImpl(IGetHostIp hostIp) {
        this.hostIp = hostIp;
    }

    @GetMapping(value = "/123")
    @ResponseBody
    public String get() {
        return "123";
    }

    @Override
    public String getCurrentHostIp() {
        GetHostIpResponseVo responseVo = HttpUtils.sendJson(hostIp, null, GetHostIpResponseVo.class);
        if (responseVo == null) {
            throw new RuntimeException("获取公网IP异常");
        }
        String ip = responseVo.getIp();
        log.info("公网ip[{}]", ip);
        return responseVo.getIp();
    }

    @Override
    public DescribeDomainRecordsResponse.Record describeDomainRecordsOne(DescribeDomainRecordsRequest request, IAcsClient client) {
        DescribeDomainRecordsResponse response;
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            throw new RuntimeException("服务链接异常");
        }
        List<DescribeDomainRecordsResponse.Record> domainRecords = response.getDomainRecords();
        if (CollectionUtils.isEmpty(domainRecords)) {
            throw new RuntimeException(String.format("暂未获取该[%s]域名记录", request.getDomainName()));
        }
        return domainRecords.get(0);
    }

    @Override
    public List<DescribeDomainRecordsResponse.Record> describeDomainRecords(DescribeDomainRecordsRequest request, IAcsClient client) {
        DescribeDomainRecordsResponse response;
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            throw new RuntimeException("服务链接异常");
        }
        List<DescribeDomainRecordsResponse.Record> domainRecords = response.getDomainRecords();
        if (CollectionUtils.isEmpty(domainRecords)) {
            throw new RuntimeException(String.format("暂未获取该[%s]域名记录", request.getDomainName()));
        }
        return domainRecords;
    }

    @Override
    public UpdateDomainRecordResponse updateDomainRecord(UpdateDomainRecordRequest request, IAcsClient client) {
        try {
            // 调用SDK发送请求
            return client.getAcsResponse(request);
        } catch (ClientException e) {
            log.info("", e);
            // 发生调用错误，抛出运行时异常
            throw new RuntimeException("域名IP修改异常");
        }
    }

    @Override
    public void updateDomainRecord(String type, String ip) {
        DescribeDomainRecordsResponse.Record record;
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        try {
            //获取域名列表
            // 主域名
            request.setDomainName(domainName);
            // 主机记录
            request.setRRKeyWord(rRKeyWord);
            // 解析记录类型
            request.setType(type);
            record = describeDomainRecordsOne(request, client);
            if (record.getValue().equals(ip)) {
                log.info("当前域名无需修改公网IP");
                return;
            }
        } catch (Exception e) {
            record = new DescribeDomainRecordsResponse.Record();
            BeanUtils.copyProperties(request, record);
        }
        {
            // 修改解析记录
            UpdateDomainRecordRequest request1 = new UpdateDomainRecordRequest();
            BeanUtils.copyProperties(record, request1);
            // 将主机记录值改为当前主机IP
            request1.setValue(ip);
            UpdateDomainRecordResponse response = updateDomainRecord(request1, client);
            log.info("DNS修改成功[{}]，原IP[{}]", response.getRequestId(), request1.getValue());
        }
    }
}
